package dao

import (
	"fmt"
	"go_server/game_server/database/mysql"
	"go_server/game_server/util"
	"go_server/zinx/zlog"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

type Build struct {
	Id string `gorm:"column:Id;primary"`
	RoleId int64 `gorm:"column:role_id"`
	MapId int32 `gorm:"column:map_id"`
	ConfigKey int32 `gorm:"column:config_key"`
	ConfigId int32 `gorm:"column:config_id"`
	BuildServerId int32 `gorm:"column:build_server_id"`
	BlockId int32 `gorm:"column:block_id"`
	BuildLevel int32 `gorm:"column:build_level"`
	BuildPosX int32`gorm:"column:build_posX"`
	BuildPosZ int32`gorm:"column:build_posZ"`
	ConsumeStatus int32`gorm:"column:consume_status"`
}

//type BuildInfo struct {
//	BuildID int32
//	BuildIndex int32
//	BuildLv int32
//	BuildPosX int32
//	BuildPosZ int32
//}



func (Build) TableName() string {
	return "build_info"
}

var(
	all_build_field = util.GetGormFields(Build{})
)

func GetBuildByKey(key string) *Build {
	db := mysql.GetServerDBConnection()
	var build Build
	if err := db.Select(all_build_field).Where("Id=?", key).First(&build).Error; err != nil {
		if err != gorm.ErrRecordNotFound {
			zlog.Errorf("GetBuildByKey ERR!!! Id: %s, err: %v", key, err)
		}
		return nil
	}
	return &build
}

func GetBuildByMapId(roleId int64, mapId int32) []*Build {
	db := mysql.GetServerDBConnection()
	var builds []*Build
	if err := db.Select(all_build_field).Where(&Build{RoleId: roleId, MapId: mapId}).
		Find(&builds).Error; err != nil {
		if err != gorm.ErrRecordNotFound {
			zlog.Errorf("GetBuildByMapId ERR!!! roleId: %d, mapId: %d, err: %v", roleId, mapId, err)
		}
		return nil
	}
	return builds
}

func UpdateBuildByKey(key string, changeField *map[string]any) {
	db := mysql.GetServerDBConnection()
	if err := db.Model(Build{}).Where("Id=?", key).Updates(changeField).Error; err != nil {
		zlog.Errorf("UpdateBuildByKey %s data failed: %v", key, err)
	}
}

func NewOrUpdateBuildData(mapId int32, datamap map[uint8][][]int32, roleId int64) {
	buildArr := make([]*Build, 0)
	for areaId, build := range datamap {
		for _, posInfo := range build {
			buildObj := &Build{
				RoleId:       roleId,
				MapId:        mapId,
				BlockId: int32(areaId),
				ConfigId: posInfo[0],
				BuildServerId: posInfo[1],
				BuildLevel: posInfo[2],
				BuildPosX: posInfo[3],
				BuildPosZ: posInfo[4],
				ConfigKey: posInfo[5],
				ConsumeStatus: posInfo[6],
				Id:   fmt.Sprint(roleId) + "-" + fmt.Sprint(mapId) + "-" + fmt.Sprint(posInfo[0]) +
					"-" + fmt.Sprint(posInfo[1]),
			}
			buildArr = append(buildArr, buildObj)
		}
	}

	db := mysql.GetServerDBConnection()
	if err := db.Clauses(clause.OnConflict{
		Columns: []clause.Column{{Name: "id"}},
		DoUpdates: clause.AssignmentColumns([]string{"block_id", "config_key", "build_level", "build_posX",
			"build_posZ", "consume_status"}),
	}).Create(buildArr).Error; err != nil {
		zlog.Errorf("create or update Build %v data failed: %v", buildArr, err)
	}
}